#include <log4cxx/logger.h>
#include <json/json.h>

#include <NameSvrCommon.h>
#include "NameSvrClientProtoHelper.h"
#include "NameSvrClient.h"
#include "ProtoHelper.h"

using namespace log4cxx;

static LoggerPtr g_logger = Logger::getLogger("NameSvrClientProtoHelper");

string ns_build_request_create_file(const char * file_path, int32_t mds_id, int32_t dir_id, int64_t file_id) {
	if (NULL == file_path || mds_id < 0 || dir_id < 0 || file_id < 0) {
		LOG4CXX_ERROR(g_logger, "ns_build_request_create_file, invalid args");
		return "";
	}
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_CREATE_FILE);
	json_object * j_file_path = json_object_new_string(file_path);
	json_object * j_mds_id = json_object_new_int(mds_id);
	json_object * j_dir_id = json_object_new_int(dir_id);
	json_object * j_file_id = json_object_new_int(file_id);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	json_object_object_add(j, "FILE_PATH", j_file_path);
	json_object_object_add(j, "MDS_ID", j_mds_id);
	json_object_object_add(j, "DIR_ID", j_dir_id);
	json_object_object_add(j, "FILE_ID", j_file_id);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;
}

string ns_build_request_delete_file(const char * file_path) {
	if (NULL == file_path) {
		LOG4CXX_ERROR(g_logger, "ns_build_request_delete_file, invalid args");
		return "";
	}
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_DELETE_FILE);
	json_object * j_file_path = json_object_new_string(file_path);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	json_object_object_add(j, "FILE_PATH", j_file_path);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;

}

string ns_build_request_create_dir(const char * dir_path) {
	if (NULL == dir_path) {
		LOG4CXX_ERROR(g_logger, "ns_build_request_create_dir, invalid args");
		return "";
	}
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_CREATE_DIR);
	json_object * j_dir_path = json_object_new_string(dir_path);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	json_object_object_add(j, "DIR_PATH", j_dir_path);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;

}

string ns_build_request_delete_dir(const char * dir_path) {
	if (NULL == dir_path) {
		LOG4CXX_ERROR(g_logger, "ns_build_request_delete_dir, invalid args");
		return "";
	}
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_DELETE_DIR);
	json_object * j_dir_path = json_object_new_string(dir_path);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	json_object_object_add(j, "DIR_PATH", j_dir_path);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;
}

string ns_build_request_get_file_metadata_info(const char * file_path) {
	if (NULL == file_path) {
		LOG4CXX_ERROR(g_logger, "ns_build_request_get_file_metadata_svr_info, invalid args");
		return "";
	}
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_GET_FILE_METADATA_INFO);
	json_object * j_file_path = json_object_new_string(file_path);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	json_object_object_add(j, "FILE_PATH", j_file_path);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;
}

string ns_build_request_alloc_mds_4_new_file() {
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_ALLOC_MDS_4_NEW_FILE);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;

}

string ns_build_request_query_is_file_exist(const char * file_path) {
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_QUERY_IS_FILE_EXIST);
	json_object * j_file_path = json_object_new_string(file_path);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	json_object_object_add(j, "FILE_PATH", j_file_path);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;

}


string ns_build_request_query_is_dir_exist(const char * dir_path) {
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_QUERY_IS_DIR_EXIST);
	json_object * j_dir_path = json_object_new_string(dir_path);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	json_object_object_add(j, "DIR_PATH", j_dir_path);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;

}


string ns_build_request_read_dir(const char * dir_path) {
	json_object * j = json_object_new_object();
	json_object * j_cmd_id = json_object_new_int(NS_CMD_READ_DIR);
	json_object * j_dir_path = json_object_new_string(dir_path);
	json_object_object_add(j, "CMD_ID", j_cmd_id);
	json_object_object_add(j, "DIR_PATH", j_dir_path);
	string request = json_object_to_json_string(j);
	json_object_put(j);
	return request;

}


int ns_parse_response_create_file(const char * response, int32_t & result) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_create_file, invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_create_file, parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	if (is_error(j_result)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_create_file, no RESULT found in response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	json_object_put(j);
	return 1;
}

int ns_parse_response_delete_file(const char * response, int32_t & result) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_delete_file, invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_delete_file, parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	if (is_error(j_result)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_delete_file, no RESULT found in response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	json_object_put(j);
	return 1;
}

int ns_parse_response_create_dir(const char * response, int32_t & result) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_create_dir, invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_create_dir, parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	if (is_error(j_result)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_create_dir, no RESULT found in response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	json_object_put(j);
	return 1;
}

int ns_parse_response_delete_dir(const char * response, int32_t & result) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_delete_dir, invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_delete_dir, parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	if (is_error(j_result)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_delete_dir, no RESULT found in response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	json_object_put(j);
	return 1;

}

int ns_parse_response_get_file_metadata_info(const char * response, int32_t & result, FILE_METADATA_INFO & info) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_get_file_metadata_svr_info, invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_get_file_metadata_svr_info, parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	json_object * j_mds_id= json_object_object_get(j, "MDS_ID");
	json_object * j_dir_id = json_object_object_get(j, "DIR_ID");
	json_object * j_file_id = json_object_object_get(j, "FILE_ID");
	json_object * j_file_type = json_object_object_get(j, "FILE_TYPE");
	json_object * j_num_hard_link = json_object_object_get(j, "NUM_HARD_LINK");

	if (is_error(j_result) || is_error(j_mds_id) || is_error(j_dir_id) || is_error(j_file_id)) {
		LOG4CXX_ERROR(g_logger, "ns_parse_response_get_file_metadata_svr_info, invalid response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	if (OK_RESULT == result) {
		info.num_hard_link  = json_object_get_int(j_num_hard_link);
		info.file_type = json_object_get_int(j_file_type);
		if (SFS_FILE_TYPE_REG_FILE == info.file_type) {
			info.mds_id = json_object_get_int(j_mds_id);
			info.dir_id = json_object_get_int(j_dir_id);
			info.file_id = json_object_get_int(j_file_id);
		}
	}
	json_object_put(j);
	return 1;
}

int ns_parse_response_alloc_mds_4_new_file(const char * response, int32_t & result, int32_t & mds_id) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	json_object * j_mds_id= json_object_object_get(j, "MDS_ID");

	if (NULL == j_result) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	if (OK_RESULT == result) mds_id = json_object_get_int(j_mds_id);
	json_object_put(j);
	return 1;
}

int ns_parse_response_query_is_file_exist(const char * response, int32_t & result, int32_t & exist_flag) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	json_object * j_exist_flag = json_object_object_get(j, "EXIST_FLAG");

	if (NULL == j_result) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	if (OK_RESULT == result) exist_flag = json_object_get_int(j_exist_flag);
	json_object_put(j);
	return 1;
}

int ns_parse_response_query_is_dir_exist(const char * response, int32_t & result, int32_t & exist_flag) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	json_object * j_exist_flag = json_object_object_get(j, "EXIST_FLAG");

	if (NULL == j_result) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	if (OK_RESULT == result) exist_flag = json_object_get_int(j_exist_flag);
	json_object_put(j);
	return 1;
}

int ns_parse_response_read_dir(const char * response, int32_t & result, list<string> & entries) {
	if (NULL == response) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid args");
		return -1;
	}
	json_object * j = json_tokener_parse(response);
	if (is_error(j)) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", parse response err:" << response);
		return -2;
	}
	json_object * j_result = json_object_object_get(j, "RESULT");
	json_object * j_entries = json_object_object_get(j, "ENTRIES");

	if (NULL == j_result) {
		LOG4CXX_ERROR(g_logger, __FUNCTION__ << ", invalid response:" << response);
		json_object_put(j);
		return -3;
	}
	result = json_object_get_int(j_result);
	if (OK_RESULT == result) {
		for(int i=0; i < json_object_array_length(j_entries); i++) {
			json_object * j_entry = json_object_array_get_idx(j_entries, i);
			entries.push_back(json_object_get_string(j_entry));
		}
	}
	json_object_put(j);
	return 1;
}
